package cn.walls1717.wallsmall.ware.service.impl;

import cn.walls1717.wallsmall.common.utils.PageUtils;
import cn.walls1717.wallsmall.common.utils.Query;
import cn.walls1717.wallsmall.ware.dao.PurchaseDao;
import cn.walls1717.wallsmall.ware.entity.PurchaseDetailEntity;
import cn.walls1717.wallsmall.ware.entity.PurchaseEntity;
import cn.walls1717.wallsmall.ware.service.PurchaseDetailService;
import cn.walls1717.wallsmall.ware.service.PurchaseService;
import cn.walls1717.wallsmall.ware.service.WareSkuService;
import cn.walls1717.wallsmall.ware.pojo.vo.MergeVO;
import cn.walls1717.wallsmall.ware.pojo.vo.PurchaseFinishVO;
import cn.walls1717.wallsmall.ware.pojo.vo.PurchaseItemDoneVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static cn.walls1717.wallsmall.common.constant.WareConstant.PurchaseStatusEnum.*;

@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Resource
    private PurchaseDetailService purchaseDetailService;
    @Resource
    private WareSkuService wareSkuService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page =
            this.page(new Query<PurchaseEntity>().getPage(params), new QueryWrapper<PurchaseEntity>());

        return new PageUtils(page);
    }

    /**
     * 分页查询出采购状态为0或1的数据
     *
     * @param params params
     * @return 采购状态为0或1的数据
     */
    @Override
    public PageUtils listPagesByStatus(Map<String, Object> params) {
        IPage<PurchaseEntity> page =
            this.page(new Query<PurchaseEntity>().getPage(params), new LambdaQueryWrapper<PurchaseEntity>()
                .eq(PurchaseEntity::getStatus, 0).or().eq(PurchaseEntity::getStatus, 1));
        return new PageUtils(page);
    }

    /**
     * 合并采购需求
     *
     * @param mergeVO 合并参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void mergePurchase(MergeVO mergeVO) {
        List<Long> purchaseDetailIds = mergeVO.getItems();
        // 如果有purchaseDetail的status不为0(新建)或者1(已分配)，那么不能进行合并
        for (Long purchaseDetailId : purchaseDetailIds) {
            PurchaseDetailEntity byId = purchaseDetailService.getById(purchaseDetailId);
            if (!Objects.equals(byId.getStatus(), CREATED.getCode())
                && !Objects.equals(byId.getStatus(), ASSIGNED.getCode())) {
                return;
            }
        }
        Long purchaseId = mergeVO.getPurchaseId();
        // 在合并采购需求的时候没有指定采购单，直接新建采购单与之关联
        if (purchaseId == null) {
            PurchaseEntity purchase = new PurchaseEntity();
            purchase.setStatus(CREATED.getCode());
            save(purchase);
            purchaseId = purchase.getId();
        }

        // 将采购单中的每一个采购需求的状态设置为已分配，并关联采购单
        Long finalPurchaseId = purchaseId;
        List<PurchaseDetailEntity> purchaseDetailEntities = purchaseDetailIds.stream().map(purchaseDetailId -> {
            PurchaseDetailEntity purchaseDetail = new PurchaseDetailEntity();
            // 设置purchaseDetailId，用于根据id批量更新
            purchaseDetail.setId(purchaseDetailId);
            // 设置purchaseId，也就是关联的采购单
            purchaseDetail.setPurchaseId(finalPurchaseId);
            // 将状态设置为1(已分配)
            purchaseDetail.setStatus(ASSIGNED.getCode());
            return purchaseDetail;
        }).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(purchaseDetailEntities);
    }

    /**
     * 领取采购单
     *
     * @param purchaseIds 采购单id集合(purchaseId)
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void receivePurchase(List<Long> purchaseIds) {
        // 将采购单purchase的状态设置为2(已领取)
        List<PurchaseEntity> purchases = purchaseIds.stream().map(this::getById)
            // 只获取状态为0(新建)或1(已分配)的采购单
            .filter(purchase -> Objects.equals(purchase.getStatus(), CREATED.getCode())
                || Objects.equals(purchase.getStatus(), ASSIGNED.getCode()))
            // 将上一步过滤器获取到的purchase状态设置为3(已领取)
            .peek(purchase -> purchase.setStatus(RECEIVE.getCode())).collect(Collectors.toList());
        this.updateBatchById(purchases);

        // 将采购单中的每一个采购信息设置为2(正在采购状态)
        purchases.forEach(purchase -> {
            List<PurchaseDetailEntity> purchaseDetails =
                purchaseDetailService.listPurchaseDetailsByPurchaseId(purchase.getId());

            List<PurchaseDetailEntity> purchaseDetailsUseUpdateStatus = purchaseDetails.stream().map(purchaseDetail -> {
                PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
                // 设置purchaseDetailId，用于根据id批量更新
                purchaseDetailEntity.setId(purchaseDetail.getId());
                // 设置采购信息的状态为2(正在采购)
                purchaseDetailEntity.setStatus(BUYING.getCode());
                return purchaseDetailEntity;
            }).collect(Collectors.toList());
            purchaseDetailService.updateBatchById(purchaseDetailsUseUpdateStatus);
        });
    }

    /**
     * 完成采购单
     *
     * @param purchaseFinishVO 相关参数
     */
    @Override
    public void finishPurchase(PurchaseFinishVO purchaseFinishVO) {
        List<PurchaseItemDoneVO> items = purchaseFinishVO.getItems();
        // 如果标志为false就代表采购信息purchaseDetail中有状态为4(有异常)的信息，那么就需要把采购单purchase的状态也置位4(有异常)
        boolean flag = true;

        // 用于存储已经设置好状态的采购单信息，进行批量更新
        List<PurchaseDetailEntity> updatePurchaseDetails = new ArrayList<>();
        // 找到状态为4(有异常的)采购信息，并设置状态
        for (PurchaseItemDoneVO item : items) {
            PurchaseDetailEntity purchaseDetail = new PurchaseDetailEntity();
            // 状态为4(有异常)，设置状态并将标志置为false
            if (Objects.equals(item.getStatus(), ERROR.getCode())) {
                // 设置状态为4
                purchaseDetail.setStatus(item.getStatus());
                flag = false;
            } else {
                // 进入这里表示状态正常，那么将状态置为3(已完成)
                purchaseDetail.setStatus(FINISH.getCode());
                PurchaseDetailEntity detail = purchaseDetailService.getById(item.getItemId());
                // 根据采购信息添加sku库存
                wareSkuService.saveStock(detail);
            }
            // 设置purchaseDetailId，用于根据id批量更新
            purchaseDetail.setId(item.getItemId());
            // 收集
            updatePurchaseDetails.add(purchaseDetail);
        }
        purchaseDetailService.updateBatchById(updatePurchaseDetails);

        // 更新采购单
        PurchaseEntity purchase = new PurchaseEntity();
        Long purchaseId = purchaseFinishVO.getId();
        purchase.setId(purchaseId);
        // flag为true设置状态为3(已完成)
        purchase.setStatus(flag ? FINISH.getCode() : ERROR.getCode());
        updateById(purchase);
    }
}